بررسی عمیق Temporal Instant API در جاوا اسکریپت برای محاسبات زمانی با دقت بالا، شامل ایجاد، دستکاری، مقایسه و موارد استفاده برای توسعهدهندگان در سراسر جهان.
Temporal Instant در جاوا اسکریپت: محاسبات زمانی با دقت بالا
جاوا اسکریپت مدتهاست که به دلیل قابلیتهای نه چندان ایدهآل خود در مدیریت تاریخ و زمان شناخته میشود. شیء قدیمی Date، با وجود استفاده گسترده، از تغییرپذیری (mutability)، رفتار متناقض API و پشتیبانی ضعیف از مناطق زمانی رنج میبرد. در اینجا Temporal API وارد میشود، یک رویکرد مدرن برای دستکاری تاریخ و زمان که برای رفع این کاستیها طراحی شده است. در قلب Temporal، شیء Instant قرار دارد که یک نقطه خاص در زمان را با دقت نانوثانیه نشان میدهد. این پست وبلاگ یک راهنمای جامع برای استفاده از Temporal.Instant برای محاسبات زمانی با دقت بالا در برنامههای جاوا اسکریپت شما ارائه میدهد و نیازهای متنوع مخاطبان جهانی را برآورده میکند.
Temporal.Instant چیست؟
Temporal.Instant یک نقطه در زمان را نشان میدهد که از مبدأ یونیکس (۱ ژانویه ۱۹۷۰، ساعت ۰۰:۰۰:۰۰ به وقت جهانی هماهنگ (UTC)) با دقت نانوثانیه اندازهگیری میشود. برخلاف شیء قدیمی Date، Temporal.Instant تغییرناپذیر (immutable) است، به این معنی که مقدار آن پس از ایجاد قابل تغییر نیست. این تغییرناپذیری برای جلوگیری از عوارض جانبی غیرمنتظره و تضمین یکپارچگی دادهها، به ویژه در برنامههای پیچیده، حیاتی است.
ایجاد اشیاء Temporal.Instant
چندین راه برای ایجاد اشیاء Temporal.Instant وجود دارد:
۱. از یک عدد (میلیثانیههای گذشته از مبدأ)
شما میتوانید یک Instant را از تعداد میلیثانیههایی که از مبدأ یونیکس گذشته است ایجاد کنید. این روش شبیه به نحوه کار شیء قدیمی Date است، اما Temporal.Instant دقت بیشتری ارائه میدهد.
const instant = Temporal.Instant.fromEpochMilliseconds(1678886400000); // March 15, 2023, 00:00:00 UTC
console.log(instant.toString()); // Output: 2023-03-15T00:00:00Z
۲. از یک عدد (نانوثانیههای گذشته از مبدأ)
برای دقت حتی بالاتر، میتوانید یک Instant را از تعداد نانوثانیههایی که از مبدأ یونیکس گذشته است ایجاد کنید. این دقیقترین راه برای نمایش یک نقطه در زمان با Temporal.Instant است.
const instant = Temporal.Instant.fromEpochNanoseconds(1678886400000000000n); // March 15, 2023, 00:00:00 UTC
console.log(instant.toString()); // Output: 2023-03-15T00:00:00Z
به استفاده از پسوند n برای نشان دادن یک BigInt literal توجه کنید. مقادیر نانوثانیه اغلب از حداکثر مقدار صحیح امن برای اعداد جاوا اسکریپت فراتر میروند، بنابراین استفاده از BigInt برای حفظ دقت ضروری است.
۳. از یک رشته ISO 8601
Temporal.Instant همچنین میتواند از یک رشته ISO 8601 که نشاندهنده تاریخ و زمان UTC است ایجاد شود.
const instant = Temporal.Instant.from('2023-03-15T00:00:00Z');
console.log(instant.toString()); // Output: 2023-03-15T00:00:00Z
const instantWithFractionalSeconds = Temporal.Instant.from('2023-03-15T00:00:00.123456789Z');
console.log(instantWithFractionalSeconds.toString()); // Output: 2023-03-15T00:00:00.123456789Z
رشته ISO 8601 باید با یک Z برای نشان دادن UTC خاتمه یابد. این رشته میتواند به صورت اختیاری شامل ثانیههای کسری با حداکثر نه رقم دقت باشد.
۴. از Temporal.Now (ساعت سیستم)
شما میتوانید لحظه کنونی در زمان را با استفاده از Temporal.Now.instant() دریافت کنید:
const now = Temporal.Now.instant();
console.log(now.toString()); // Output: Varies depending on the current time
کار با اشیاء Temporal.Instant
هنگامی که یک شیء Temporal.Instant دارید، میتوانید عملیات مختلفی روی آن انجام دهید. به یاد داشته باشید که اشیاء Temporal.Instant تغییرناپذیر هستند، بنابراین این عملیات به جای تغییر شیء اصلی، اشیاء Temporal.Instant جدیدی را برمیگردانند.
۱. افزودن و کاستن زمان
شما میتوانید با استفاده از متدهای add() و subtract() زمان را به یک Instant اضافه یا از آن کم کنید. این متدها یک شیء Temporal.Duration را میپذیرند که یک بازه زمانی را نشان میدهد.
const instant = Temporal.Instant.from('2023-03-15T00:00:00Z');
const duration = Temporal.Duration.from({ hours: 2, minutes: 30 });
const futureInstant = instant.add(duration);
console.log(futureInstant.toString()); // Output: 2023-03-15T02:30:00Z
const pastInstant = instant.subtract(duration);
console.log(pastInstant.toString()); // Output: 2023-03-14T21:30:00Z
شما همچنین میتوانید از یک نمایش رشتهای برای مدت زمان استفاده کنید:
const instant = Temporal.Instant.from('2023-03-15T00:00:00Z');
const futureInstant = instant.add('PT2H30M'); // ISO 8601 duration string
console.log(futureInstant.toString()); // Output: 2023-03-15T02:30:00Z
۲. مقایسه Instant ها
شما میتوانید دو شیء Temporal.Instant را با استفاده از متد compare() مقایسه کنید. این متد برمیگرداند:
-1اگر instant اول زودتر از دومی باشد.0اگر دو instant برابر باشند.1اگر instant اول دیرتر از دومی باشد.
const instant1 = Temporal.Instant.from('2023-03-15T00:00:00Z');
const instant2 = Temporal.Instant.from('2023-03-15T01:00:00Z');
console.log(Temporal.Instant.compare(instant1, instant2)); // Output: -1
console.log(Temporal.Instant.compare(instant2, instant1)); // Output: 1
console.log(Temporal.Instant.compare(instant1, instant1)); // Output: 0
۳. تبدیل به سایر انواع Temporal
Temporal.Instant میتواند به انواع دیگر Temporal مانند Temporal.ZonedDateTime، Temporal.PlainDateTime و Temporal.PlainDate تبدیل شود. این برای کار با مناطق زمانی و نمایشهای محلی تاریخ و زمان ضروری است.
الف. به Temporal.ZonedDateTime
Temporal.ZonedDateTime یک تاریخ و زمان را با یک منطقه زمانی مشخص نشان میدهد. برای تبدیل یک Instant به ZonedDateTime، باید منطقه زمانی را مشخص کنید.
const instant = Temporal.Instant.from('2023-03-15T00:00:00Z');
const zonedDateTime = instant.toZonedDateTimeISO('America/Los_Angeles');
console.log(zonedDateTime.toString()); // Output: 2023-03-14T17:00:00-07:00[America/Los_Angeles]
متد toZonedDateTimeISO() یک ZonedDateTime را با استفاده از تقویم ISO 8601 ایجاد میکند. شما همچنین میتوانید از toZonedDateTime() برای مشخص کردن یک تقویم متفاوت استفاده کنید.
ب. به Temporal.PlainDateTime
Temporal.PlainDateTime یک تاریخ و زمان بدون منطقه زمانی را نشان میدهد. برای تبدیل یک Instant به PlainDateTime، ابتدا باید آن را به یک ZonedDateTime تبدیل کرده و سپس PlainDateTime را از آن دریافت کنید.
const instant = Temporal.Instant.from('2023-03-15T00:00:00Z');
const zonedDateTime = instant.toZonedDateTimeISO('America/Los_Angeles');
const plainDateTime = zonedDateTime.toPlainDateTime();
console.log(plainDateTime.toString()); // Output: 2023-03-14T17:00:00
ج. به Temporal.PlainDate
Temporal.PlainDate یک تاریخ بدون زمان یا منطقه زمانی را نشان میدهد. مشابه PlainDateTime، ابتدا به ZonedDateTime تبدیل میکنید.
const instant = Temporal.Instant.from('2023-03-15T00:00:00Z');
const zonedDateTime = instant.toZonedDateTimeISO('America/Los_Angeles');
const plainDate = zonedDateTime.toPlainDate();
console.log(plainDate.toString()); // Output: 2023-03-14
۴. دریافت میلیثانیهها و نانوثانیهها از مبدأ
شما میتوانید تعداد میلیثانیهها یا نانوثانیههایی که از مبدأ یونیکس گذشته است را به ترتیب با استفاده از خصوصیات epochMilliseconds و epochNanoseconds بازیابی کنید.
const instant = Temporal.Instant.from('2023-03-15T00:00:00.123456789Z');
console.log(instant.epochMilliseconds); // Output: 1678886400123
console.log(instant.epochNanoseconds); // Output: 1678886400123456789n
موارد استفاده برای Temporal.Instant
Temporal.Instant به ویژه در سناریوهایی که محاسبات زمانی با دقت بالا مورد نیاز است، مفید است. در اینجا چند مثال آورده شده است:
۱. ثبت وقایع و حسابرسی
هنگام ثبت وقایع یا حسابرسی فعالیت سیستم، ثبت زمان دقیق وقوع یک رویداد حیاتی است. Temporal.Instant دقت لازم برای ثبت دقیق مهرهای زمانی را فراهم میکند.
function logEvent(eventDescription) {
const timestamp = Temporal.Now.instant().toString();
console.log(`[${timestamp}] ${eventDescription}`);
}
logEvent('User logged in');
logEvent('File saved');
۲. اندازهگیری عملکرد
اندازهگیری عملکرد کد نیاز به زمانبندی دقیق دارد. Temporal.Instant میتواند برای اندازهگیری زمان اجرای بلوکهای کد با دقت نانوثانیه استفاده شود.
const start = Temporal.Now.instant();
// Code to measure
for (let i = 0; i < 1000000; i++) {
// Some operation
}
const end = Temporal.Now.instant();
const duration = end.since(start);
console.log(`Execution time: ${duration.total('milliseconds')} milliseconds`);
۳. سیستمهای توزیعشده و همگامسازی دادهها
در سیستمهای توزیعشده، حفظ سازگاری دادهها در چندین گره اغلب به همگامسازی زمانی دقیق نیاز دارد. Temporal.Instant میتواند برای نمایش مهرهای زمانی برای بهروزرسانی دادهها و حل تضادها بر اساس زمان استفاده شود.
به عنوان مثال، سناریویی را در نظر بگیرید که دادهها در چندین سرور در مکانهای جغرافیایی مختلف تکثیر میشوند (مثلاً یک شبکه تحویل محتوا یا یک پایگاه داده توزیعشده). اگر کاربری یک رکورد را بهروزرسانی کند، سیستم باید اطمینان حاصل کند که آخرین بهروزرسانی به طور مداوم در تمام سرورها منتشر میشود. استفاده از Temporal.Instant برای مهر زمانی هر بهروزرسانی، ترتیب دقیق را تضمین میکند، حتی با وجود تأخیر شبکه و انحراف احتمالی ساعت بین سرورها.
۴. تراکنشهای مالی
تراکنشهای مالی اغلب برای انطباق با مقررات و ثبت دقیق سوابق به مهرهای زمانی با دقت بالا نیاز دارند. زمان دقیق یک معامله، پرداخت یا انتقال باید به طور دقیق ثبت شود تا از اختلافات جلوگیری شده و پاسخگویی تضمین شود.
به عنوان مثال، سیستمهای معاملات با فرکانس بالا به دقت میکروثانیه یا نانوثانیه برای ثبت لحظه دقیق اجرای یک سفارش نیاز دارند. حتی اختلافات کوچک در زمانبندی میتواند منجر به عواقب مالی قابل توجهی شود. Temporal.Instant وضوح مورد نیاز برای این برنامههای حیاتی را فراهم میکند.
۵. کاربردهای علمی
بسیاری از کاربردهای علمی، مانند نجوم، شبیهسازیهای فیزیک و ثبت دادهها از آزمایشها، به اندازهگیریهای زمانی بسیار دقیق نیاز دارند. این اندازهگیریها اغلب برای تجزیه و تحلیل دادهها و نتیجهگیریهای دقیق حیاتی هستند.
تصور کنید یک تلسکوپ در حال جمعآوری داده از یک ستاره دوردست است. زمانبندی دقیق هر مشاهده برای تعیین موقعیت، حرکت و سایر ویژگیهای ستاره ضروری است. Temporal.Instant به دانشمندان اجازه میدهد تا این مهرهای زمانی را با دقت لازم ثبت کنند.
بینالمللیسازی و مناطق زمانی
در حالی که Temporal.Instant یک نقطه در زمان را به وقت UTC نشان میدهد، هنگام کار با تاریخ و زمان برای مخاطبان جهانی، در نظر گرفتن مناطق زمانی مهم است. همانطور که قبلاً نشان داده شد، میتوانید یک Instant را به یک Temporal.ZonedDateTime تبدیل کنید تا همان نقطه در زمان را در یک منطقه زمانی خاص نشان دهید.
هنگام نمایش تاریخ و زمان به کاربران، همیشه از منطقه زمانی محلی آنها برای جلوگیری از سردرگمی استفاده کنید. شما میتوانید منطقه زمانی کاربر را از مرورگر یا سیستم عامل او دریافت کنید. به عنوان مثال، میتوانید از Intl.DateTimeFormat API برای قالببندی تاریخ و زمان مطابق با منطقه و منطقه زمانی کاربر استفاده کنید.
const instant = Temporal.Instant.from('2023-03-15T00:00:00Z');
const zonedDateTime = instant.toZonedDateTimeISO(Temporal.Now.timeZone());
const formatter = new Intl.DateTimeFormat(undefined, {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
timeZoneName: 'short',
});
console.log(formatter.format(zonedDateTime)); // Output: Varies depending on the user's locale and time zone
این مثال از منطقه زمانی سیستم کاربر استفاده میکند. در صورت نیاز میتوانید Temporal.Now.timeZone() را با یک شناسه منطقه زمانی خاص (مثلاً 'America/Los_Angeles') جایگزین کنید.
نکته: همیشه هنگام کار با مناطق زمانی به تغییر ساعت تابستانی (DST) توجه داشته باشید. قوانین منطقه زمانی ممکن است تغییر کنند، بنابراین استفاده از یک پایگاه داده بهروز مناطق زمانی برای اطمینان از محاسبات دقیق مهم است. Temporal API به طور خودکار تغییرات DST را هنگام تبدیل بین مناطق زمانی مدیریت میکند.
پشتیبانی مرورگر و محیط
تا اواخر سال ۲۰۲۳، Temporal API هنوز نسبتاً جدید است و در همه مرورگرها و محیطهای جاوا اسکریپت به طور کامل پشتیبانی نمیشود. ممکن است برای پشتیبانی از مرورگرهای قدیمیتر نیاز به استفاده از یک polyfill داشته باشید.
بسته @js-temporal/polyfill یک polyfill برای Temporal API فراهم میکند. شما میتوانید آن را با استفاده از npm یا yarn نصب کنید:
npm install @js-temporal/polyfill
سپس، polyfill را در کد جاوا اسکریپت خود وارد کنید:
import '@js-temporal/polyfill';
این کار Temporal API را به دامنه سراسری اضافه میکند و به شما امکان میدهد حتی اگر محیط به طور بومی از آن پشتیبانی نکند، از آن در کد خود استفاده کنید.
بهترین شیوهها و ملاحظات
- برای ذخیرهسازی و محاسبات داخلی از UTC استفاده کنید: تمام مهرهای زمانی را به وقت UTC ذخیره کنید تا از مشکلات مربوط به منطقه زمانی جلوگیری شود. فقط هنگام نمایش تاریخ و زمان به کاربران، به مناطق زمانی محلی تبدیل کنید.
- تبدیل مناطق زمانی را با دقت انجام دهید: از تغییرات DST و قوانین منطقه زمانی آگاه باشید. برای اطمینان از تبدیلهای دقیق، از یک پایگاه داده بهروز مناطق زمانی استفاده کنید.
- برای مقادیر نانوثانیه از BigInt استفاده کنید: مقادیر نانوثانیه اغلب از حداکثر مقدار صحیح امن برای اعداد جاوا اسکریپت فراتر میروند. برای حفظ دقت از BigInt استفاده کنید.
- استفاده از polyfill را در نظر بگیرید: اگر نیاز به پشتیبانی از مرورگرها یا محیطهای قدیمیتر دارید، از بسته
@js-temporal/polyfillاستفاده کنید. - کد خود را به طور کامل آزمایش کنید: کد خود را با مناطق زمانی و محلیهای مختلف آزمایش کنید تا اطمینان حاصل کنید که برای همه کاربران به درستی کار میکند.
- فرضیات خود را مستند کنید: هرگونه فرضی که در مورد مناطق زمانی، محلیها یا قالبهای تاریخ و زمان دارید را به وضوح مستند کنید.
نتیجهگیری
Temporal.Instant یک روش قوی و دقیق برای نمایش نقاط زمانی در جاوا اسکریپت فراهم میکند. تغییرناپذیری، دقت نانوثانیه و ادغام آن با سایر انواع Temporal، آن را به ابزاری قدرتمند برای مدیریت محاسبات زمانی پیچیده در انواع برنامهها تبدیل کرده است. با درک نحوه ایجاد، دستکاری و مقایسه اشیاء Instant و با پیروی از بهترین شیوهها برای بینالمللیسازی و مدیریت منطقه زمانی، میتوانید قابلیتهای تاریخ و زمان قابل اعتماد و دقیقی برای مخاطبان جهانی بسازید. پذیرش Temporal API، از جمله شیء Instant، به توسعهدهندگان این امکان را میدهد که از محدودیتهای شیء قدیمی Date فراتر رفته و برنامههای قویتر و قابل نگهداریتری بسازند که پیچیدگیهای زمان را در فرهنگها و مناطق مختلف به دقت منعکس میکنند.
با گسترش پذیرش Temporal API، این API در آستانه تبدیل شدن به استاندارد دستکاری تاریخ و زمان در جاوا اسکریپت قرار دارد. توسعهدهندگانی که با ویژگیها و بهترین شیوههای آن آشنا شوند، برای ساخت نسل بعدی برنامههای آگاه از زمان به خوبی مجهز خواهند بود.